{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# K210【目标检测】模型的训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取git代码构建环境"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 环境搭建好后，就不需要重新构建。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# %%bash\n",
    "# if [ -d \"/home/aistudio/work/k210\" ]; then\n",
    "#   rm -f -r \"/home/aistudio/work/k210\"\n",
    "# fi\n",
    "# # git代码没更新，就没必要删除重新获取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Cloning into 'k210'...\n"
     ]
    }
   ],
   "source": [
    "# %%bash\n",
    "# cd /home/aistudio/work/\n",
    "# git clone https://gitee.com/ai-liam/k210\n",
    "# # #git clone https://github.com/ai-liam/k210\n",
    "# # 下载过就不必要下载"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mkdir: cannot create directory ‘/home/aistudio/external-libraries’: File exists\n"
     ]
    }
   ],
   "source": [
    "!mkdir /home/aistudio/external-libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "## 安装过就必要在安装\n",
    "#!pip install -r /home/aistudio/work/k210/k210_train/requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ -t /home/aistudio/external-libraries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 上传和设置数据源目录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 把你的 xx.zip 数据上到 work目录，【注意，解压得到的文件名】参考例子数据\n",
    "upload_zip = \"/home/aistudio/data/data110386/detector_xml_format.zip\"\n",
    "#upload_zip = f\"/home/aistudio/work/k210/datasets/detector_xml_format.zip\"# demo数据\n",
    "data_unzip = \"/home/aistudio/data/temp/\"\n",
    "data_unzip_last = data_unzip+\"xml_format/\" #最后解压后的目录"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "## 解压过就不用再解压\n",
    "import os\n",
    "\n",
    "cmd = f\"unzip -o -d {data_unzip} {upload_zip}\"\n",
    "f=os.popen(cmd)\n",
    "print(f.read())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 开始训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2412779.ipynb  data  external-libraries  work\n"
     ]
    }
   ],
   "source": [
    "import sys \n",
    "sys.path.append('/home/aistudio/external-libraries')\n",
    "sys.path.append('/home/aistudio/work/k210/k210_train')\n",
    "\n",
    "!ls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import os, sys\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "from train.detector_v1 import detector_train\n",
    "from train.detector.instance import config\n",
    "\n",
    "config.detector_train_epochs = 4 # 修改训练轮数 40"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2021-09-27_11_03\n"
     ]
    }
   ],
   "source": [
    "cur_time = time.strftime(\"%Y-%m-%d_%H_%M\", time.localtime())\n",
    "print(cur_time)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "root_dir: /home/aistudio/work/k210\n",
      "temp_saves_dir: /home/aistudio/work/k210/ubuntu/out/imgn_2021-09-27_11_03/\n",
      "datasets_dir: /home/aistudio/data/temp/xml_format/\n"
     ]
    }
   ],
   "source": [
    "root_dir = os.path.abspath('./work/k210') #\"/home/aistudio/work/k210\"\n",
    "ubuntu_path = f\"out/imgn_{cur_time}\" #用来mac中生成kmodel\n",
    "temp_saves_dir = f\"{root_dir}/ubuntu/{ubuntu_path}/\" #保存文件目录\n",
    "datasets_dir =  data_unzip_last #数据源\n",
    "\n",
    "print(\"root_dir:\",root_dir)\n",
    "print(\"temp_saves_dir:\",temp_saves_dir)\n",
    "print(\"datasets_dir:\",datasets_dir)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<os._wrap_close object at 0x7f138e586c50>\n"
     ]
    }
   ],
   "source": [
    "## 清理隐藏文件\n",
    "cmd1 = f\"rm -f {datasets_dir}/.DS_Store\"\n",
    "cmd = f\"rm -f {datasets_dir}/*/.DS_Store\"\n",
    "os.popen(cmd1)\n",
    "f = os.popen(cmd)\n",
    "print(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "select gpu fail:NVML Shared Library Not Found\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2021-09-27 11:03:43,202 - [INFO]:  no GPU, will use [CPU]\n",
      "2021-09-27 11:03:43,202 - [INFO]:  no GPU, will use [CPU]\n",
      "INFO:logger: no GPU, will use [CPU]\n",
      "2021-09-27 11:03:43,209 - [INFO]:  input_shape: (224, 224, 3)\n",
      "2021-09-27 11:03:43,209 - [INFO]:  input_shape: (224, 224, 3)\n",
      "INFO:logger: input_shape: (224, 224, 3)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-- 0\n",
      "-- 1\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2021-09-27 11:03:45,966 - [INFO]:  load datasets complete, check pass, images num:600, bboxes num:600\n",
      "2021-09-27 11:03:45,966 - [INFO]:  load datasets complete, check pass, images num:600, bboxes num:600\n",
      "INFO:logger: load datasets complete, check pass, images num:600, bboxes num:600\n",
      "2021-09-27 11:03:46,047 - [INFO]:  train, labels:['0', '1']\n",
      "2021-09-27 11:03:46,047 - [INFO]:  train, labels:['0', '1']\n",
      "INFO:logger: train, labels:['0', '1']\n",
      "2021-09-27 11:03:46,052 - [DEBUG]:  train, datasets dir:/home/aistudio/data/temp/xml_format/\n",
      "2021-09-27 11:03:46,052 - [DEBUG]:  train, datasets dir:/home/aistudio/data/temp/xml_format/\n",
      "DEBUG:logger: train, datasets dir:/home/aistudio/data/temp/xml_format/\n",
      "2021-09-27 11:03:46,056 - [INFO]:  bboxes num: 600, first bbox: [0.52232143 0.50892857]\n",
      "2021-09-27 11:03:46,056 - [INFO]:  bboxes num: 600, first bbox: [0.52232143 0.50892857]\n",
      "INFO:logger: bboxes num: 600, first bbox: [0.52232143 0.50892857]\n",
      "2021-09-27 11:03:46,505 - [INFO]:  bbox accuracy(IOU): 85.43%\n",
      "2021-09-27 11:03:46,505 - [INFO]:  bbox accuracy(IOU): 85.43%\n",
      "INFO:logger: bbox accuracy(IOU): 85.43%\n",
      "2021-09-27 11:03:46,507 - [INFO]:  bound boxes: (54.000000,57.00),(78.000000,77.00),(165.000000,165.00),(105.000000,105.00),(136.000000,131.00)\n",
      "2021-09-27 11:03:46,507 - [INFO]:  bound boxes: (54.000000,57.00),(78.000000,77.00),(165.000000,165.00),(105.000000,105.00),(136.000000,131.00)\n",
      "INFO:logger: bound boxes: (54.000000,57.00),(78.000000,77.00),(165.000000,165.00),(105.000000,105.00),(136.000000,131.00)\n",
      "2021-09-27 11:03:46,509 - [INFO]:  anchors: [1.6875, 1.78125, 2.4375, 2.40625, 5.15625, 5.15625, 3.28125, 3.28125, 4.25, 4.09375]\n",
      "2021-09-27 11:03:46,509 - [INFO]:  anchors: [1.6875, 1.78125, 2.4375, 2.40625, 5.15625, 5.15625, 3.28125, 3.28125, 4.25, 4.09375]\n",
      "INFO:logger: anchors: [1.6875, 1.78125, 2.4375, 2.40625, 5.15625, 5.15625, 3.28125, 3.28125, 4.25, 4.09375]\n",
      "2021-09-27 11:03:46,519 - [INFO]:  w/h ratios: [0.95, 1.0, 1.0, 1.01, 1.04]\n",
      "2021-09-27 11:03:46,519 - [INFO]:  w/h ratios: [0.95, 1.0, 1.0, 1.01, 1.04]\n",
      "INFO:logger: w/h ratios: [0.95, 1.0, 1.0, 1.01, 1.04]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "self.anchors: [1.6875, 1.78125, 2.4375, 2.40625, 5.15625, 5.15625, 3.28125, 3.28125, 4.25, 4.09375]\n",
      "load local weight file: /home/aistudio/work/k210/k210_train/train/detector/weights/mobilenet_7_5_224_tf_no_top.h5\n",
      "Model: \"model\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 224, 224, 3)]     0         \n",
      "_________________________________________________________________\n",
      "mobilenet_0.75_224 (Function (None, 7, 7, 768)         1832976   \n",
      "=================================================================\n",
      "Total params: 1,832,976\n",
      "Trainable params: 1,816,560\n",
      "Non-trainable params: 16,416\n",
      "_________________________________________________________________\n",
      "Model: \"model_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 224, 224, 3)]     0         \n",
      "_________________________________________________________________\n",
      "mobilenet_0.75_224 (Function (None, 7, 7, 768)         1832976   \n",
      "_________________________________________________________________\n",
      "detection_layer_35 (Conv2D)  (None, 7, 7, 35)          26915     \n",
      "_________________________________________________________________\n",
      "reshape (Reshape)            (None, 7, 7, 5, 7)        0         \n",
      "=================================================================\n",
      "Total params: 1,859,891\n",
      "Trainable params: 1,843,475\n",
      "Non-trainable params: 16,416\n",
      "_________________________________________________________________\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/aistudio/external-libraries/keras/optimizer_v2/optimizer_v2.py:356: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.\n",
      "  \"The `lr` argument is deprecated, use `learning_rate` instead.\")\n",
      "/home/aistudio/external-libraries/keras/engine/training_v1.py:1228: UserWarning: `model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n",
      "  warnings.warn('`model.fit_generator` is deprecated and '\n",
      "2021-09-27 11:03:57,864 - [INFO]:  train start\n",
      "2021-09-27 11:03:57,864 - [INFO]:  train start\n",
      "INFO:logger: train start\n",
      "2021-09-27 11:03:57,869 - [INFO]:  progress: 1.0%, train start\n",
      "2021-09-27 11:03:57,869 - [INFO]:  progress: 1.0%, train start\n",
      "INFO:logger: progress: 1.0%, train start\n",
      "2021-09-27 11:03:57,875 - [INFO]:  epoch 0 start\n",
      "2021-09-27 11:03:57,875 - [INFO]:  epoch 0 start\n",
      "INFO:logger: epoch 0 start\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/4\n",
      "  8/480 [..............................] - ETA: 25:36 - batch: 3.5000 - size: 5.0000 - loss: 1.139"
     ]
    }
   ],
   "source": [
    "# 配置文件：detector.instance\n",
    "result,_,model_path,anchors,labels = detector_train(datasets_dir=datasets_dir,temp_datasets_dir=temp_saves_dir,config=config)\n",
    "\n",
    "#result,_,model_path,anchors,labels = detector_train(datasets_zip_path=datasets_dir,temp_datasets_dir=temp_saves_dir,config=config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "print(model_path)\n",
    "print(\"anchors:\",anchors)\n",
    "print(\"labels:\",labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 生成k210专用模型 kmodel"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "'''\n",
    "上传 ncc文件\n",
    "下载：https://github.com/kendryte/nncase/releases/tag/v0.1.0-rc5\n",
    "\n",
    "unzip -o -d /home/aistudio/work/ /home/aistudio/work/ncc-linux-x86_64.zip\n",
    "目录为：\n",
    "~/work$ ls\n",
    "ncc-linux-x86_64  ncc-linux-x86_64.zip\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "ncc_path = \"/home/aistudio/work/ncc-linux-x86_64/ncc\" # ncc目录\n",
    "cmd_linux = f\"{ncc_path} -i tflite -o k210model --dataset {temp_saves_dir}sample_images {temp_saves_dir}m.tflite {temp_saves_dir}result/m.kmodel\"\n",
    "print(cmd_linux)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "f=os.popen(cmd_linux)\n",
    "print(f.read())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 生成的文件\n",
    "cmd = f\"ls {temp_saves_dir}result\"\n",
    "print(\"cmd:\",cmd)\n",
    "f=os.popen(cmd)\n",
    "print(f.read())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 生成k210程序boot.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "target_file = f\"{temp_saves_dir}result/boot.py\"\n",
    "copy_file = f\"cp -f {root_dir}/k210_train/data/template/yolo_boot.py {target_file}\"\n",
    "print(copy_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "f=os.popen(copy_file)\n",
    "print(f.read())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 更新 labels \n",
    "result_boot_py_path = target_file\n",
    "\n",
    "img_size = [224,224]\n",
    "#labels = [\"0\", \"1\"]\n",
    "replace = 'labels = [\"{}\"]'.format('\", \"'.join(labels))\n",
    "\n",
    "with open(result_boot_py_path) as f:\n",
    "            boot_py = f.read()\n",
    "with open(result_boot_py_path, \"w\") as f:\n",
    "            target = 'labels = [\"0\", \"1\"] # labels'\n",
    "            boot_py = boot_py.replace(target, replace)\n",
    "            target = 'anchors = [3.28125, 3.28125] # anchors'\n",
    "            replace = 'anchors = [{}]'.format(', '.join(str(i) for i in anchors))\n",
    "            target = 'img_size = [224,224] # img_size'\n",
    "            replace = 'img_size = [{},{}]'.format(img_size[0], img_size[1])\n",
    "            boot_py = boot_py.replace(target, replace)\n",
    "            f.write(boot_py)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 更新到k210 的cube硬件上运行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 生成的文件\n",
    "cmd = f\"ls {temp_saves_dir}result\"\n",
    "print(\"cmd:\",cmd)\n",
    "f=os.popen(cmd)\n",
    "print(f.read())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "'''\n",
    "把 \n",
    "├── result\n",
    "│   ├── boot.py\n",
    "│   └── m.kmodel\n",
    "\n",
    "的 boot.py ，m.kmodel 复制到 sd 卡的根目录下（或者 models/m8/目录下）\n",
    "重新启动硬件，就可以运行了\n",
    "boot.py 代码中核实模型的路径是否正确\n",
    "'''"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
